package encryption;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * 1.DES：数据加密标准，是对称加密算法领域中的典型算法
 * 2.特点：密钥偏短（56位）、生命周期短（避免被破解）
 * https://www.jb51.net/article/102127.htm
 */
public class DES {

    /**
     * 16进制的字符串表示转成字节数组
     *
     * @param hexString 16进制格式的字符串
     * @return 转换后的字节数组
     **/
    public static byte[] toByteArray(String hexString) {
        if (hexString.isEmpty())
            throw new IllegalArgumentException("this hexString must not be empty");

        hexString = hexString.toLowerCase();
        final byte[] byteArray = new byte[hexString.length() / 2];
        int k = 0;
        for (int i = 0; i < byteArray.length; i++) {//因为是16进制，最多只会占用4位，转换成字节需要两个16进制的字符，高位在先
            byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 0xff);
            byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 0xff);
            byteArray[i] = (byte) (high << 4 | low);
            k += 2;
        }
        return byteArray;
    }

    /**
     * 字节数组转成16进制表示格式的字符串
     *
     * @param byteArray 需要转换的字节数组
     * @return 16进制表示格式的字符串
     **/
    public static String toHexString(byte[] byteArray) {
        if (byteArray == null || byteArray.length < 1)
            throw new IllegalArgumentException("this byteArray must not be null or empty");

        final StringBuilder hexString = new StringBuilder();
        for (int i = 0; i < byteArray.length; i++) {
            if ((byteArray[i] & 0xff) < 0x10)//0~F前面不零
                hexString.append("0");
            hexString.append(Integer.toHexString(0xFF & byteArray[i]));
        }
        return hexString.toString().toLowerCase();
    }

    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {
        //生成密钥
        KeyGenerator keyGen = KeyGenerator.getInstance("DES");//密钥生成器
        keyGen.init(56);//初始化密钥生成器
        SecretKey secretKey = keyGen.generateKey();//生成密钥
        byte[] key = secretKey.getEncoded();//密钥字节数组

        //加密
        SecretKey secretKey2 = new SecretKeySpec(key, "DES");//恢复密钥
        Cipher cipher = Cipher.getInstance("DES");//Cipher完成加密或解密工作类
        cipher.init(Cipher.ENCRYPT_MODE, secretKey2);//对Cipher初始化，加密模式
        String data = "123543";
        System.out.println("加密前" + data);
        byte[] cipherByte = cipher.doFinal(toByteArray(data));//加密data
        String newStr = toHexString(cipherByte);
        System.out.println("加密后" + newStr);

//        //解密
////        SecretKey secretKey = new SecretKeySpec(key, "DES");//恢复密钥
////        Cipher cipher = Cipher.getInstance("DES");//Cipher完成加密或解密工作类
////        cipher.init(Cipher.DECRYPT_MODE, secretKey);//对Cipher初始化，解密模式
////        byte[] cipherByte2 = cipher.doFinal(cipherByte);//解密data
        String resultStr = toHexString(cipher.doFinal(cipherByte));
        System.out.println("解密后" + resultStr);

    }
}
